package com.msg.test;

import com.msg.test.model.MsgCommand;
import com.msg.test.model.MsgConfig;
import com.msg.test.model.MsgConnect;
import com.msg.test.model.MsgSubmit;
import com.msg.test.util.MsgUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Created by Administrator on 2017/10/19 0019.
 */
public class MessageService {
    private static Log log = LogFactory.getLog(MessageService.class);
    private static Socket socket;
    private static DataInputStream in;
    private static DataOutputStream out;

    public static boolean sendShortMsg(String msg,String mobile){
        try{
            SocketService socket = new SocketService(getOutputSream(),getInputStream());

            int sequence = MsgUtil.getSequence();
            byte[] msgByte = msg.getBytes("gb2312");
            MsgSubmit submit = new MsgSubmit();
            //消息头12 +8+1+1+1+1+10+1+21+1+1+1+6+2+6+17+17+21+1+21+1+8
            submit.setTotalLength(159+msgByte.length);
            submit.setCommandId(MsgCommand.CMPP_SUBMIT);
            submit.setSequence(sequence);
            submit.setPkTotal((byte)(0x01));
            submit.setPkNumber((byte)0x01);
            submit.setRegisteredDelivery((byte)0x00);
            submit.setMsgLevel((byte)0x01);
            submit.setFeeUserType((byte)0x02);
            submit.setFeeTerminalId("");
            submit.setTpPId((byte)0x00);
            submit.setTpUdhi((byte)0x00);
            submit.setMsgFmt((byte)0x0f);
            submit.setMsgSrc(MsgConfig.getSpId());
            submit.setSrcId(MsgConfig.getSpCode());
            submit.setDestTerminalId(mobile);
            submit.setMsgLength((byte)msgByte.length);
            submit.setMsgContent(msgByte);

            List<byte[]> byteList = new ArrayList<byte[]>();
            byteList.add(submit.toByteArray());

            socket.setDataList(byteList);

            log.info("向手机号码：" + mobile + "下发短短信，序列号：" + sequence);
            boolean success = socket.start();
            if (success){
                log.info("发送成功：" + mobile);
            }else {
                log.info("发送失败：" + mobile);
            }
            return true;
        }catch (Exception ex){
            try {
                out.close();
            }catch (IOException ioe){
                out = null;
            }
            log.error("发送短短信" + ex.getMessage());
            return false;
        }
    }

    public static boolean sendLongMsg(String msg,String mobile){
        try {
            byte[] allByte = msg.getBytes("iso-10646-ucs-2");
            List<byte[]> dataList = new ArrayList<byte[]>();
            int msgLength = allByte.length;
            int maxLength = 140;
            int msgSendCount = msgLength%(maxLength - 6) == 0 ?msgLength/(maxLength - 6):msgLength/(maxLength - 6) + 1;
            //短信息内容头拼接
            byte[] msgHead = new byte[6];
            Random random = new Random();
            random.nextBytes(msgHead);
            msgHead[0]=0x05;
            msgHead[1]=0x00;
            msgHead[2]=0x03;
            msgHead[3]=0x03;
            msgHead[4]=(byte)msgSendCount;
            msgHead[5]=0x01;
            int seqId = MsgUtil.getSequence();
            for (int i = 0; i < msgSendCount; i++){
                msgHead[5] = (byte)(i+1);
                byte[] needMsg = null;
                if (i != msgSendCount - 1){
                    int start = (maxLength - 6) * i;
                    int end = (maxLength - 6) * (i + 1);
                    needMsg = MsgUtil.getMsgBytes(allByte,start,end);
                }else {
                    int start = (maxLength -6) * i;
                    int end = allByte.length;
                    needMsg = MsgUtil.getMsgBytes(allByte,start,end);
                }
                int subLength = needMsg.length + msgHead.length;
                byte[] sendMsg = new byte[needMsg.length + msgHead.length];
                System.arraycopy(msgHead,0,sendMsg,0,6);
                System.arraycopy(needMsg,0,sendMsg,0,needMsg.length);
                MsgSubmit submit = new MsgSubmit();
                submit.setTotalLength(159 + subLength);
                submit.setCommandId(MsgCommand.CMPP_SUBMIT);
                submit.setSequence(seqId);
            }

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return
    }

    private static Socket getSocketInstance(){
        if (socket == null || socket.isClosed() || !socket.isConnected()){
            try{
                socket = new Socket(MsgConfig.getIsmgIp(),MsgConfig.getIsmgPort());
                socket.setKeepAlive(true);
                socket.setSoTimeout(MsgConfig.getTimeOut());

                int count  = 0;
                boolean result = connectISMG();
                while (!result){
                    count++;
                    result = connectISMG();
                    if (count >= (MsgConfig.getConnectCount() - 1)){
                        break;
                    }
                }
            }catch (UnknownHostException ex){
                log.error("网关链接端口号错误！"+ex.getMessage());
            }
            catch (IOException ex){
                log.error("网关链接失败！"+ex.getMessage());
            }
        }
        return socket;
    }

    private static DataOutputStream getOutputSream(){
        if (out == null || null == socket || socket.isClosed() || !socket.isConnected()){
            try {
                out = new DataOutputStream(MessageService.getSocketInstance().getOutputStream());
            } catch (IOException e) {
                out = null;
            }
        }
        return out;
    }
    private static DataInputStream getInputStream(){
        if (in == null || null == socket || socket.isClosed() || !socket.isConnected()){
            try {
                in = new DataInputStream(MessageService.getSocketInstance().getInputStream());
            } catch (IOException e) {
                in = null;
            }
        }
        return in;
    }

    private static boolean connectISMG(){
        log.info("请求连接到IMSG...");
        MsgConnect connect = new MsgConnect();
        connect.setTotalLength(12+6+16+1+4);//消息总长度，级总字节数:4+4+4(消息头)+6+16+1+4(消息主体)
        connect.setCommandId(MsgCommand.CMPP_CONNECT);
        connect.setSequence(MsgUtil.getSequence());
        connect.setSourceAddr(MsgConfig.getSpId());
        String timestamp = MsgUtil.getTimestamp();
        connect.setAuthenticatorSource(MsgUtil.getAuthenticatorSource(MsgConfig.getSpId(),MsgConfig.getSharedSecret(),timestamp));
        connect.setTimestamp(Integer.parseInt(timestamp));
        connect.setVersion((byte)0x20);
        List<byte[]> dataList = new ArrayList<byte[]>();
        dataList.add(connect.toByteArray());
        SocketService sendConnect = new SocketService(getOutputSream(),getInputStream());
        sendConnect.setDataList(dataList);
        try{
            boolean success = sendConnect.start();
            if (success){
                log.info("请求连接到IMSG...链接成功");
            }else{
                log.info("请求连接到IMSG...链接失败");
            }
            return true;
        }catch (Exception ex){
            try {
                out.close();
            } catch (IOException e) {
                out=null;
            }
            return false;
        }
    }
}
